package com.MyBatis.test_1_28_mybatis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Test128MyBatisApplication {

    public static void main(String[] args) {
        SpringApplication.run(Test128MyBatisApplication.class, args);

        // ***** MyBatis *****

        // 需要准备两个准备工作
        // 1.SQL语句
        // 2.数据库对象和Java对象映射

        // **** 什么是 MyBatis ****
        // MyBatis是⼀款 持久层 框架，⽤于简化JDBC的开发。
        //• MyBatis本是 Apache的⼀个开源项⽬iBatis，2010年这个项⽬由apache迁移到了google code，并
        //且改名为MyBatis 。2013年11⽉迁移到Github。
        //持久层：指的就是持久化操作的层, 通常指数据访问层(dao), 是⽤来操作数据库的.

        // MyBatis 的写法
        // 有两中
        // 1. xml

        // 2. 注解


        // 先看注解的方式
        // 第一步 引人入 MyBatis依赖, 引入对应的数据库的依赖,比如MySQL
        // 第二步 配置数据库相关信息
        // 第三步 定义Java对象
        // 第四步 写实现

        // 开发规范:
        // 使用MyBatis对数据库的操作类,也叫 xxxMapper

        // 企业建表规范
        // 需要准备3的字段
        // 1. id
        // 2. 创建时间
        // 3. 更新时间
        // 哪怕需要的只是一个字段,也要把这三个准备上

        //且: 在创建字段/表名的时候 全部使用小写,不使用大写

        // 使用MyBatis可能会遇到的问题
        // 1. 配置相关的问题: 1.没有配置数据库相关信息,会显示找不到url
        //                 2.配置了,但是显示账号密码错误, 显示的是: user 'root'@'localhost' 之类的日志信息
        //                 3.还有一种 数据库错了: 显示的是: Unknown database '' 之类的日志信息
        //                 4.表不存在: 显示的是: BadSql...之类的日志
        //                 5.字段错误: 依然会显示BadSql...之类的日志.
        //  2. 也有接口返回的类型错了, 也要看日志

        // **** MyBatis 相关的配置 ****
        // 通过配置:
        // 如:
        //  mybatis:
        //   configuration: # 配置打印 MyBatis⽇志
        //    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
        // 也是在测试类运行的控制台里面看

        //  对于 MyBatis 都在 mapper 层里面操作

        // 接下来看 xml 的方式
        //  第一步: 需要配置数据库
        //         跟使用注解的方式 一样
        //  第二步: 指明 xml 的路径
        //         使用配置
        //             mybatis:
        //              mapper-locations: classpath:mapper/**Mapper.xml
        //  classpath 指的是 resources 这个文件, 后面的 mapper 是可以自己随便起的,
        //  但是要注意,在建包的时候要和这个名字保持一致,  **Mapper 表示xml的格式, 如果什么文件都要的话,用 ** 表示, 指定了以Mapper结束
        //  第三步: 写xml的实现
        //         要先声明: 注解 和 xml 的方式是可以共存的


        // 常见问题:
        //      方法没有找到对应的实现:
        //         有一下可能:
        //          1. xml 和 接口 定义的方法名称不一致
        //          2. Mapper路径配置和xml的路径不一致
        //          3. xml 的 namespace 写错了
        // 对于 数据库配置结构报错的 xml 的方式 和 注解的方式不一样
        //   如果看到 dataSource 之类的报错信息, 就去找配置里面的内容, 是不是错了


        // **** 多表查询 ****
        // 工作中是尽量避免使用多表查询的, 尤其是对性能要求非常高的
        // 还是在 Mapper 层中演示

        // ****  #{} 和 ${} ****
        // MyBatis 参数赋值有两种⽅式, 咱们前⾯使⽤了 #{} 进⾏赋值, 接下来我们看下⼆者的区别
        // # 和 $的区别
        // 这两个都是用来获取变量

        // 使用 #查询
        // 打印的日志里面, 在传参的时候是用 ? 来代替的  // 这样的叫   预编译SQL
        // 但当进行,按照名字查询的时候, # 还是跟查询id方式的一致
        // 使用 $查询
        // 打印的日志里面, 在传参的时候是直接把值赋值进去了 // 这样的叫 即时SQL
        // 按照名字查询的时候 $ 就需要加上 引号了 如: '${username}' , 数据库那边也要加上 引号

        // 所以 显现的区别就是:
        // 如果 # 时, 如果参数是 String 类型, 会自动加上 ''
        // 如果 $ 时, 如果参数是 String 类型, 就不会自动加上 '',
        //          $是直接符号拼接, 所以要进行 字符串查询的时候要给 $这个加上 ''

        // 那么 $ 这个到底有什么用呢?
        // 接下来有一些场景 非 $ 使用不可
        // 就是实现排序的时候
        // 在 UserInfoMapper 包中演示
        // 如果查询使用 # 的话 会报错, 因为 # 会自动把参数加上 引号, 而我们不想这样, 所以我们 应该使用 $

        // 还有一种场景, 那就是实现模糊查询的时候
        // 使用 # 也会报错, 也应该使用 $

        // 以上这种情况, 加上引号是小事
        // 但是 $存在的漏洞: SQL注入, 才去让我们更多的是使用 #
        // SQL注入 : 是通过操作输⼊的数据来修改事先定义好的SQL语句，以达到执⾏代码对服务器进⾏攻击的⽅法。

        // # 不会存在这样的问题

        // 运行之后 表象看着两者是没有什么区别的
        // 但其实是 预编译sql 和 即时sql的区别
        //          1. 预编译sql 性能更高 (会把语法解析部分,语法优化部分, 语法编译部分进行缓存了)
        //          2. 预编译sql 不存在 SQL 注入的问题
        //        排序时 不能使用#
        //              表名,字段名等作为参数时不能使用 #
        //        模糊查询时, 如果使用 # 需要搭配 mysql 的内置函数
        //        而不能直接使用.

        // SQL执行:
        // 要进行 1.语法解析
        //       2.SQL优化
        //       3.SQL的执行

        // 所以呢 # 的 模糊查询是不能使用的
        // 怎么解决呢? 可以用SQL内置函数操作来完成
        // like CONCAT('%','xiaozuo','%')

        // 实际开发中, 能使用 # 的, 都使用 #
        //  使用$ 时 一定要考虑 sql注入问题


        // ***** 数据库连接池 *****
        // 池: 就是把一些要用到的东西放在一个池子里面

        // 数据库连接池: 数据库连接池负责分配、管理和释放数据库连接，它允许应⽤程序重复使⽤⼀个现有的数据库连接，
        //⽽不是再重新建⽴⼀个

        // 常⻅的数据库连接池：
        //• C3P0
        //• DBCP
        //• Druid
        //• Hikari
        //⽬前⽐较流⾏的是 Hikari, Druid

        // . Hikari : SpringBoot默认使⽤的数据库连接池
        // Hikari 是⽇语"光"的意思(ひかり), Hikari也是以追求性能极致为⽬标
        // 2. Druid
        //如果我们想把默认的数据库连接池切换为Druid数据库连接池, 只需要引⼊相关依赖即可
        // Druid连接池是阿⾥巴巴开源的数据库连接池项⽬
        //• 功能强⼤，性能优秀，是Java语⾔最好的数据库连接池之⼀
        //• 学习⽂档: https://github.com/alibaba/druid/wiki/%E9%A6%96%E9%A1%B5





    }

}
